home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / term / metafont.trm < prev    next >
Text File  |  1993-09-15  |  15KB  |  419 lines

  1. /*
  2.  * $Id: metafont.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
  3.  */
  4.  
  5. /*
  6.  *              GNUPLOT -- mf.trm
  7.  *
  8.  *            This terminal driver supports:
  9.  *               Metafont Plot Commands
  10.  *
  11.  * Written by : Pl Hedne
  12.  *        Trondheim, Norway
  13.  *        Pal.Hedne@termo.unit.no
  14.  */
  15.  
  16. /*
  17.  * Improvements and bug fixes by Carsten Steger:
  18.  * - Set default plot size to 5 by 3 inches as in the latex- and eepic-
  19.  *   drivers
  20.  * - Fixed some bugs concerning resolution dependent output
  21.  * - Added MF_scale function
  22.  * - Added MF_justify_text function and modified MF_put_text function and
  23.  *   put_text macro accordingly
  24.  * - Modified MF_move and MF_vector to make output shorter and modified
  25.  *   MF_text accordingly
  26.  * - Added various linetypes by plotting dashed lines; had to modify
  27.  *   MF_linetype and MF_vector for this
  28.  * - Added MF_arrow function
  29.  * - All global variables and #define'd names begin with MF_ now
  30.  * As a consequence almost nothing of the original code by Pl Hedne remains
  31.  * but credit goes to him for the ingenious trick of storing the character
  32.  * images into picture variables, without which this driver would have been
  33.  * impossible for me to write.
  34.  */
  35.  
  36. #define MF_DPI (300)
  37. /* resolution of printer we expect to use; the value itself is not
  38.  * particularly important... it is here only for compatibility to the
  39.  * LaTeX-driver and to get the spacing right. */
  40.  
  41. /* 5 inches wide by 3 inches high (default) */
  42. #define MF_XSIZE 5.0
  43. #define MF_YSIZE 3.0
  44. #define MF_XMAX (MF_XSIZE*MF_DPI)
  45. #define MF_YMAX (MF_YSIZE*MF_DPI)
  46.  
  47. #define MF_HTIC (5*MF_DPI/72)
  48. #define MF_VTIC (5*MF_DPI/72)
  49. #define MF_HCHAR (MF_DPI*53/10/72)
  50. #define MF_VCHAR (MF_DPI*11/72)
  51.  
  52. /* Plot size in inches */
  53. static double MF_xsize = MF_XSIZE;
  54. static double MF_ysize = MF_YSIZE;
  55. static int MF_char_code;
  56. static int MF_ang;
  57. static int MF_line_type;
  58. static enum JUSTIFY MF_justify;
  59. static double MF_dist_left;
  60. static int MF_is_solid;
  61. static int MF_picked_up_pen;
  62. /* 
  63.  * We keep track of where we are with respect to dashed lines by using
  64.  * the next five variables. MF_dash_index indicates which element of
  65.  * MF_lines[..].dashlen should be used. The MF_last.. variables keep
  66.  * track of the position of the pen.
  67.  */
  68. static int MF_dash_index;
  69. static unsigned int MF_last_x, MF_last_y;
  70.  
  71. static struct {
  72.   int solid;         /* Is the line solid? */
  73.   float thickness;   /* Thickness of pen we are going to use */
  74.   int dashlen[4];    /* Length of individual segments; even: line; odd: gap */
  75. } MF_lines[10] = {
  76.   {1,1.5,0,0,0,0},
  77.   {0,1.0,MF_DPI/60,MF_DPI/50,MF_DPI/60,MF_DPI/50},
  78.   {1,1.5,0,0,0,0},
  79.   {0,1.5,MF_DPI/20,MF_DPI/30,MF_DPI/20,MF_DPI/30},
  80.   {0,1.5,MF_DPI/30,MF_DPI/20,MF_DPI/30,MF_DPI/20},
  81.   {0,1.5,MF_DPI/15,MF_DPI/30,MF_DPI/60,MF_DPI/30},
  82.   {0,1.5,MF_DPI/30,MF_DPI/50,MF_DPI/30,MF_DPI/50},
  83.   {0,1.5,MF_DPI/20,MF_DPI/50,MF_DPI/60,MF_DPI/30},
  84.   {0,1.5,MF_DPI/30,MF_DPI/50,MF_DPI/30,MF_DPI/30},
  85.   {0,1.5,MF_DPI/60,MF_DPI/50,MF_DPI/60,MF_DPI/30}
  86.   /* dash: line,     gap,      line,     gap      */
  87. };
  88.  
  89.  
  90.  
  91. int MF_init ()
  92. {
  93.   MF_char_code = 0;
  94.   MF_ang = 0;
  95.  
  96.   fputs ("if unknown cmbase: input cmbase fi\n\n", outfile);
  97.   fputs ("tracingstats:=1;\n", outfile);
  98.   fputs ("picture r[];\n", outfile);
  99.   fputs ("\ndef openit = openwindow currentwindow\n", outfile);
  100.   fputs ("  from (0,0) to (400,800) at (-50,500) enddef;\n", outfile);
  101.  
  102.   fputs ("\nmode_setup;\n", outfile);
  103.  
  104.   fputs ("\n%Include next eight lines if you have problems with the mode on your system..\n", outfile);
  105.   fputs ("%proofing:=0;\n", outfile);
  106.   fputs ("%fontmaking:=1;\n", outfile);
  107.   fputs ("%tracingtitles:=0;\n", outfile);
  108.   fputs ("%pixels_per_inch:=300;\n", outfile);
  109.   fputs ("%blacker:=0;\n", outfile);
  110.   fputs ("%fillin:=.2;\n", outfile);
  111.   fputs ("%o_correction:=.6;\n", outfile);
  112.   fputs ("%fix_units;\n", outfile);
  113.  
  114.   /* Next lines must be included if text support is needed (CM base used) */
  115.   fputs ("\ndef put_text(expr ts,xstart,ystart,rot,justification) =\n", outfile);
  116.   fputs ("  begingroup\n", outfile);
  117.   fputs ("    text_width:=0;text_height:=0;\n", outfile);
  118.   fputs ("    for ind:=0 step 1 until length(ts)-1:\n", outfile);
  119.   fputs ("      dec_num:=ASCII substring (ind,ind+1) of ts;\n", outfile);
  120.   fputs ("      if unknown r[dec_num]: dec_num:=32; fi\n", outfile);
  121.   fputs ("      if dec_num=32: \n", outfile);
  122.   fputs ("        text_width:=text_width+wd[65];\n", outfile);
  123.   fputs ("        text_height:=max(text_height,ht[65]+dp[65]);\n", outfile);
  124.   fputs ("      elseif dec_num>=0: \n", outfile);
  125.   fputs ("        text_width:=text_width+wd[dec_num];\n", outfile);
  126.   fputs ("        text_height:=max(text_height,ht[dec_num]+dp[dec_num]);\n", outfile);
  127.   fputs ("      fi\n", outfile);
  128.   fputs ("    endfor\n", outfile);
  129.   fputs ("    if rot=90:\n", outfile);
  130.   fputs ("      if justification=1: ynext:=ystart;\n", outfile);
  131.   fputs ("      elseif justification=2: ynext:=round(ystart-text_width/2);\n", outfile);
  132.   fputs ("      else: ynext:=round(ystart-text_width);\n", outfile);
  133.   fputs ("      fi\n", outfile);
  134.   fputs ("      xnext:=xstart+text_height/2;\n", outfile);
  135.   fputs ("    else:\n", outfile);
  136.   fputs ("      if justification=1: xnext:=xstart;\n", outfile);
  137.   fputs ("      elseif justification=2: xnext:=round(xstart-text_width/2);\n", outfile);
  138.   fputs ("      else: xnext:=round(xstart-text_width);\n", outfile);
  139.   fputs ("      fi\n", outfile);
  140.   fputs ("      ynext:=ystart-text_height/2;\n", outfile);
  141.   fputs ("    fi\n", outfile);
  142.   fputs ("    for ind:=0 step 1 until length(ts)-1:\n", outfile);
  143.   fputs ("      dec_num:=ASCII substring (ind,ind+1) of ts;\n", outfile);
  144.   fputs ("      if unknown r[dec_num]: dec_num:=32; fi\n", outfile);
  145.   fputs ("      if dec_num=32: \n", outfile);
  146.   fputs ("        xnext:=xnext+wd[65]*cosd rot;\n", outfile);
  147.   fputs ("        ynext:=ynext+wd[65]*sind rot;\n", outfile);
  148.   fputs ("      elseif dec_num>=0: \n", outfile);
  149.   fputs ("        currentpicture:=currentpicture+r[dec_num] shifted(xnext,ynext)\n", outfile);
  150.   fputs ("          rotatedaround ((xnext,ynext),rot); \n", outfile);
  151.   fputs ("        xnext:=xnext+wd[dec_num]*cosd rot;\n", outfile);
  152.   fputs ("        ynext:=ynext+wd[dec_num]*sind rot;\n", outfile);
  153.   fputs ("      fi\n", outfile);
  154.   fputs ("    endfor\n", outfile);
  155.   fputs ("  endgroup \n", outfile);
  156.   fputs ("enddef;\n", outfile);
  157.  
  158.   fputs ("\ndef endchar =\n", outfile);
  159.   fputs ("  r[charcode]:=currentpicture;\n", outfile);
  160.   fputs ("  wd[charcode]:=w;ht[charcode]:=h;dp[charcode]:=d;\n", outfile);
  161.   fputs ("  message \"Picture of charcode no.\" & decimal charcode;\n", outfile);
  162.   fputs ("  endgroup;\n", outfile);
  163.   fputs ("enddef;\n", outfile);
  164.   fputs ("let endchar_ = endchar;\n", outfile);
  165.   fputs ("let generate = relax;\n", outfile);
  166.   fputs ("let roman = relax;\n", outfile);
  167.  
  168.   fputs ("input cmr10.mf\n", outfile);
  169.   fputs ("if ligs>1: font_coding_scheme:=\"TeX text\";\n", outfile);
  170.   fputs ("  spanish_shriek=oct\"074\"; spanish_query=oct\"076\";\n", outfile);
  171.   fputs ("else: font_coding_scheme:=\n", outfile);
  172.   fputs ("  if ligs=0: \"TeX typewriter text\"\n", outfile);
  173.   fputs ("  else: \"TeX text without f-ligatures\" fi;\n", outfile);
  174.   fputs ("  spanish_shriek=oct\"016\"; spanish_query=oct\"017\"; fi\n", outfile);
  175.   fputs ("font_setup;\n", outfile);
  176.   fputs ("input romanu.mf %Roman uppercase.\n", outfile);
  177.   fputs ("input romanl.mf %Roman lowerrcase.\n", outfile);
  178.   fputs ("input greeku.mf %Greek uppercase.\n", outfile);
  179.   fputs ("input romand.mf %Numerals.\n", outfile);
  180.   fputs ("input romanp.mf %Ampersand, question marks, currency sign.\n", outfile);
  181.   fputs ("input romspl.mf %Lowercase specials (dotless \\i, ligature \\ae, etc.)\n", outfile);
  182.   fputs ("input romspu.mf %Uppercase specials (\\AE, \\OE, \\O)\n", outfile);
  183.   fputs ("input punct.mf %Punctuation symbols.\n", outfile);
  184.   fputs ("\nminus=ASCII\"-\"; cmchar \"Minus sign\";\n", outfile);
  185.   fputs ("beginarithchar(minus); \n", outfile);
  186.   fputs ("  pickup rule.nib;\n", outfile);
  187.   fputs ("  lft x1=hround 1.5u-eps;\n", outfile);
  188.   fputs ("  x2=w-x1; y1=y2=math_axis;\n", outfile);
  189.   fputs ("  draw z1--z2;     % bar\n", outfile);
  190.   fputs ("  labels(1,2); \n", outfile);
  191.   fputs ("endchar;\n", outfile);
  192.  
  193.   fputs ("\ncmchar \"Period\";\n", outfile);
  194.   fputs ("  numeric dot_diam#; dot_diam#:=if monospace: 5/4 fi\\ dot_size#;\n", outfile);
  195.   fputs ("  define_whole_blacker_pixels(dot_diam);\n", outfile);
  196.   fputs ("  beginchar(\".\",5u#,dot_diam#,0);\n", outfile);
  197.   fputs ("  adjust_fit(0,0); pickup fine.nib;\n", outfile);
  198.   fputs ("  pos1(dot_diam,0); pos2(dot_diam,90);\n", outfile);
  199.   fputs ("  lft x1l=hround(.5w-.5dot_diam); bot y2l=0; z1=z2; dot(1,2);    % dot\n", outfile);
  200.   fputs ("  penlabels(1,2);\n", outfile);
  201.   fputs ("endchar;\n", outfile);
  202.  
  203.   fputs ("\ndef endchar =\n", outfile);
  204.   fputs ("  % Next line should probably be removed if CM base is used\n", outfile);
  205.   fputs ("  l:=0; r:=w;\n", outfile);
  206.   fputs ("  %Include the next two lines if you want to\n", outfile);
  207.   fputs ("  %rotate the picture 90 deg.(Portrait to Landscape)\n", outfile);
  208.   fputs ("  %currentpicture:=currentpicture rotated 90 shifted (h,0);\n", outfile);
  209.   fputs ("  %tmp:=charht; charht:=charwd; charwd:=tmp;\n", outfile);
  210.   fputs ("  scantokens extra_endchar;\n", outfile);
  211.   fputs ("  if proofing>0: makebox(proofrule); fi\n", outfile);
  212.   fputs ("  chardx:=w;\n", outfile);
  213.   fputs ("  shipit;\n", outfile);
  214.   fputs ("  if displaying>0: makebox(screenrule); showit; fi\n", outfile);
  215.   fputs ("  endgroup \n", outfile);
  216.   fputs ("enddef;\n", outfile);
  217.   fputs ("let endchar_ = endchar;\n", outfile);
  218.   fputs ("let generate = input;\n", outfile);
  219.   fputs ("let roman = roman;\n", outfile);
  220.  
  221.   fputs ("\n\nfont_identifier:=\"GNUPLOT\";\n", outfile);
  222.   /* font_size must be bigger than em#/16 by METAFONT rules.
  223.    * Therefore make it pretty big so big figures will be
  224.    * handled correctly. Setting font_size to 72pt# lets us
  225.    * handle characters up to 15.94 by 15.94 inches. */
  226.   fputs ("font_size 72pt#;\n", outfile);
  227.   fputs ("th#=0.4pt#; define_whole_pixels(th);\n", outfile);
  228.   fputs ("\npath arrowhead;\n", outfile);
  229.   fputs ("arrowhead = (-7pt,-2pt){dir30}..(-6pt,0pt)..", outfile);
  230.   fputs ("{dir150}(-7pt,2pt) &\n", outfile);
  231.   fputs ("  (-7pt,2pt)--(0pt,0pt)--(-7pt,-2pt) & cycle;\n", outfile);
  232. }
  233.  
  234.  
  235. int MF_graphics ()
  236. {
  237.   register struct termentry *t = &term_tbl[term];
  238.  
  239.   fprintf (outfile, "\n\nbeginchar(%d,%gin#,%gin#,0);\n",
  240.            MF_char_code, MF_xsize, MF_ysize);
  241.   MF_char_code++;
  242.   fprintf (outfile, "a:=w/%d;b:=h/%d;\n", t->xmax, t->ymax);
  243.   MF_picked_up_pen = 0;
  244. }
  245.  
  246.  
  247. int MF_text ()
  248. {
  249.   fprintf (outfile, "endchar;\n");
  250. }
  251.  
  252.  
  253. int MF_justify_text (mode)
  254. enum JUSTIFY mode;
  255. {
  256.   MF_justify = mode;
  257.   return TRUE;
  258. }
  259.  
  260.  
  261. int MF_text_angle (ang)
  262. int ang;
  263. {
  264.   if (ang > 0) MF_ang = 90;
  265.   else MF_ang = 0;
  266.   return TRUE;
  267. }
  268.  
  269.  
  270. int MF_linetype (linetype)
  271. int linetype;
  272. {
  273.   if (linetype >=8) linetype %= 8;
  274.   linetype += 2;
  275.   /* Only output change in pens if it actually affects the pen used */
  276.   if ((MF_lines[linetype].thickness != MF_lines[MF_line_type].thickness) ||
  277.       (!MF_picked_up_pen)) {
  278.     fprintf (outfile, "pickup pencircle scaled %gth;\n",
  279.              MF_lines[linetype].thickness);
  280.     MF_picked_up_pen = 1;
  281.   }
  282.   MF_line_type = linetype;
  283.   MF_dash_index = 0;
  284.   MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
  285.   MF_is_solid = MF_lines[MF_line_type].solid;
  286. }
  287.  
  288.  
  289. int MF_scale (xs, ys)
  290. double xs, ys;
  291. {
  292.   struct termentry *t = &term_tbl[term];
  293.  
  294.   t->xmax = (unsigned int) (MF_XMAX * xs);
  295.   t->ymax = (unsigned int) (MF_YMAX * ys);
  296.   MF_xsize = MF_XSIZE * xs;
  297.   MF_ysize = MF_YSIZE * ys;
  298.   return TRUE;
  299. }
  300.  
  301.  
  302. int MF_move (x, y)
  303. unsigned int x, y;
  304. {
  305.   MF_last_x = x;
  306.   MF_last_y = y;
  307.   MF_dash_index = 0;
  308.   MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
  309. }
  310.  
  311.  
  312. int MF_vector (x, y)
  313. unsigned int x, y;
  314. {
  315.   double sqrt(), floor();
  316.  
  317.   if (MF_is_solid) {
  318.     if (x == MF_last_x && y == MF_last_y)
  319.       fprintf (outfile, "drawdot (%da,%db);\n", x, y);
  320.     else
  321.       fprintf (outfile, "draw (%da,%db)--(%da,%db);\n",
  322.                MF_last_x, MF_last_y, x, y);
  323.   } else {
  324.     double dist_to_go, delta_x, delta_y, inc_x, inc_y;
  325.     double last_x_d, last_y_d, next_x_d, next_y_d;
  326.     unsigned int next_x, next_y;
  327.  
  328.     if (x == MF_last_x && y == MF_last_y) {
  329.       if (! (MF_dash_index & 1))
  330.         fprintf (outfile, "drawdot (%da,%db);\n", x, y);
  331.     } else {
  332.       last_x_d = MF_last_x;
  333.       last_y_d = MF_last_y;
  334.       delta_x = x - last_x_d;
  335.       delta_y = y - last_y_d;
  336.       dist_to_go = sqrt (delta_x * delta_x + delta_y * delta_y);
  337.       inc_x = delta_x / dist_to_go;
  338.       inc_y = delta_y / dist_to_go;
  339.       while (MF_dist_left < dist_to_go) {
  340.         next_x_d = last_x_d + inc_x * MF_dist_left;
  341.         next_y_d = last_y_d + inc_y * MF_dist_left;
  342.         next_x = floor (next_x_d + 0.5);
  343.         next_y = floor (next_y_d + 0.5);
  344.         /* MF_dash_index & 1 == 0 means: draw a line; otherwise just move */
  345.         if (! (MF_dash_index & 1))
  346.           fprintf (outfile, "draw (%da,%db)--(%da,%db);\n",
  347.                    MF_last_x, MF_last_y, next_x, next_y);
  348.         MF_last_x = next_x;
  349.         MF_last_y = next_y;
  350.         last_x_d = next_x_d;
  351.         last_y_d = next_y_d;
  352.         dist_to_go -= MF_dist_left;
  353.         MF_dash_index = (MF_dash_index + 1) & 3;
  354.         MF_dist_left = MF_lines[MF_line_type].dashlen[MF_dash_index];
  355.       }
  356.       delta_x = x - last_x_d;
  357.       delta_y = y - last_y_d;
  358.       MF_dist_left -= sqrt (delta_x * delta_x + delta_y * delta_y);
  359.       if (! (MF_dash_index & 1)) {
  360.         if (x == MF_last_x && y == MF_last_y)
  361.           fprintf (outfile, "drawdot (%da,%db);\n", x, y);
  362.         else
  363.           fprintf (outfile, "draw (%da,%db)--(%da,%db);\n",
  364.                    MF_last_x, MF_last_y, x, y);
  365.       }
  366.     }
  367.   }
  368.   MF_last_x = x;
  369.   MF_last_y = y;
  370. }
  371.  
  372.  
  373. int MF_arrow (sx, sy, ex, ey, head)
  374. unsigned int sx, sy, ex, ey;
  375. TBOOLEAN head;
  376. {
  377.   int delta_x, delta_y;
  378.  
  379.   MF_move (sx, sy);
  380.   MF_vector (ex, ey);
  381.   if (head) {
  382.     delta_x = ex - sx;
  383.     delta_y = ey - sy;
  384.     fprintf (outfile, "fill arrowhead rotated angle(%d,%d) shifted (%da,%db);\n",
  385.              delta_x, delta_y, ex, ey);
  386.   } 
  387. }
  388.  
  389.  
  390. int MF_put_text (x, y, str)
  391. unsigned int x, y;
  392. char *str;
  393. {
  394.   int i, j;
  395.  
  396.   for (i = 0; i < strlen (str); i++)
  397.     if (str[i] == '"')
  398.       str[i] = '\'';        /* Replace " with ' */
  399.   switch (MF_justify) {
  400.     case LEFT:
  401.       j = 1;
  402.       break;
  403.     case CENTRE:
  404.       j = 2;
  405.       break;
  406.     case RIGHT:
  407.       j = 3;
  408.       break;
  409.   }
  410.   fprintf (outfile, "put_text(\"%s\",%da,%db,%d,%d);\n",
  411.            str, x, y, MF_ang, j);
  412. }
  413.  
  414.  
  415. int MF_reset ()
  416. {
  417.   fprintf (outfile, "end.\n");
  418. }
  419.